#include "tcp.h"
#include "ui_tcp.h"

QString addr2 = "www.cylk.codes"; //默认网盘服务端地址，测试用，按需更改
//转换域名为ip地址
QHostInfo info2 = QHostInfo::fromName(addr2);  //优先转换为ipv6地址，注意ipv6端口是否被封
const QString ip2 = info2.addresses().first().toString();
const quint16 port = 3003;


tcp::tcp(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::tcp)
{
    ui->setupUi(this);

    socket = new QTcpSocket(this);
    myTimer = new QTimer;
    flag = 1;
    ui->btnDown->setEnabled(false);     //未连接时关闭按钮
    ui->btnFile->setEnabled(false);
    ui->btnSend->setEnabled(false);
    ui->btnLook->setEnabled(false);
    ui->progressBar->setValue(0);
    //ui->clientFile->append(ip);

    ui->yourIP->setText(getHostIpAddress());

    connect(myTimer,&QTimer::timeout,[=](){
        //关闭定时器
        myTimer->stop();
        sendData();

    });
}

tcp::~tcp()
{
    delete ui;
}

void tcp::on_btnC_clicked()
{
    socket->connectToHost(ip2,port); //连接服务
    if(socket->waitForConnected(500))
    {
        connect(socket,&QTcpSocket::disconnected,[=](){
            qDebug()<<"断开连接";
            socket->close();
        });
        connect(socket,&QTcpSocket::readyRead,[=](){
            QByteArray arr = socket->readAll();
            if(flag == 1)           //收到请求
            {
                if(arr.at(0) == '*') //获取服务器已存文件信息
                {
                    recvFileInfo(arr);
                }
                if(arr.at(0) == '#') //获取发送文件信息，名字，数据大小
                {
                    flag = 2;
                    qDebug()<<"--------"<<flag;
                    fileName = QString(arr).section("#",1,1);
                    fileSize = QString(arr).section("#",2,2).toInt();
                    recvSize = 0;
                    QString path=QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/";

                    file.setFileName(path+fileName);

                    bool isok = file.open(QIODevice::WriteOnly);
                    if(isok == false)
                    {
                        qDebug() << "接受失败";
                        socket->disconnectFromHost();
                        socket->close();
                    }

                    //初始化进度条
                    ui->progressBar->setMinimum(0);
                    ui->progressBar->setMaximum(fileSize/1024);
                }
            }
            else if(flag == 2)
            {
                downLoad(arr);
            }

        });
        QMessageBox::information(this,"tips","连接成功");
        ui->btnDown->setEnabled(true);
        ui->btnFile->setEnabled(true);
        ui->btnSend->setEnabled(true);
        ui->btnLook->setEnabled(true);
    }
    else
    {
        QMessageBox::information(this,"tips","连接失败");
    }
}



void tcp::recvFileInfo(QByteArray &arr){        //添加服务器文件名到QListWidgetItem
    ui->serverFile->clear();
    ui->serverFile->addItem("服务器列表");
    QString data;
    QStringList list = data.prepend(arr).split("*");
    for(int i = 0; i < list.size(); i++)
    {
        QListWidgetItem *tmpItem = new QListWidgetItem(list.at(i));
        ui->serverFile->addItem(tmpItem);
    }
    flag = 1;
}


void tcp::on_btnFile_clicked()  //选择发送文件
{
    ui->clientFile->clear();
    //获取文件路劲
    QString filepath = QFileDialog::getOpenFileName(this,"选择文件","../");
    if(filepath.isEmpty() == false)
    {
        QFileInfo info(filepath);
        fileName = info.fileName();
        qDebug()<<fileName;
        fileSize = info.size();
        sendSize = 0;
        //打开文件只读

        file.setFileName(filepath);
        bool isok = file.open(QIODevice::ReadOnly);
        if(isok == false)
        {
            qDebug()<<"打开失败";
        }
        //显示文件路径
        ui->clientFile->append(filepath);
    }
}


void tcp::on_btnSend_clicked() //发送文件
{
    //发送文件信息
    QString data = QString("#%1#%2").arg(fileName).arg(fileSize);
    qint64 len = socket->write(data.toUtf8().data());
    if(len > 0)
    {
        qDebug()<<"发送文件信息成功";

        //沾包问题,用定时器解决沾包问题
        myTimer->start(20);//间隔20毫秒触发timeout信号
        ui->progressBar->setMinimum(0);
        ui->progressBar->setMaximum(fileSize/1024);
    }
    else
    {
        qDebug()<<"发送文件信息失败";
        file.close();
    }
}

void tcp::sendData(){
    qint64 len = 0;
    do{
        char buf[4096] = {0};
        //读文件的内容
        len = file.read(buf,sizeof(buf));

        len = socket->write(buf,len);
        //统计已经发送的文件内容总数
        sendSize+=len;
        ui->progressBar->setValue(sendSize/1024);

    }while(len>0);

    if(sendSize == fileSize)
    {
        QMessageBox::information(this,"tips","文件已经全部发送完毕");
    }
}


void tcp::on_btnDown_clicked()  //下载文件
{
    //先判断文件名是否存在，没有选择文件就返回并且提醒
    if(fileServer.isEmpty())
    {
        QMessageBox::warning(this,"警告","没有选择文件");
        return;
    }
    //发送命令$下载，并且把文件名字发送过去
    QString data = QString("$%1").arg(fileServer);
    socket->write(data.toUtf8());
}


void tcp::on_serverFile_itemClicked(QListWidgetItem *item)  //选择服务器文件名
{
    fileServer = item->text();
}

void tcp::downLoad(QByteArray &arr){    //写入文件
    //发送过来的是文件
    qint64 len = file.write(arr);
    recvSize +=len;
    ui->progressBar->setValue(recvSize/1024);
    if(recvSize == fileSize)
    {
        QMessageBox::information(this,"tips","文件下载完毕");
        file.close();  //关闭文件
        flag = 1;
    }
}


void tcp::on_btnLook_clicked()  //发送获取网盘文件请求
{
    socket->write("*");
    qDebug() << "已发送";
    //ui->clientFile->append("已发送");
}

QString tcp::getHostIpAddress(){        //获取IPv4内网地址
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    QString strIpAddress;

    foreach (QNetworkInterface interface, interfaces) {
        if (interface.flags().testFlag(QNetworkInterface::IsUp) &&
            interface.flags().testFlag(QNetworkInterface::IsRunning) &&
            !interface.flags().testFlag(QNetworkInterface::IsLoopBack))
        {
            foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol &&
                    entry.ip().toString().startsWith("192.168.150")) // 做测试用，视情况做修改
                {
                    strIpAddress = entry.ip().toString();
                    break;
                }
            }
        }
        if (!strIpAddress.isEmpty())
            break;
    }

    // If no IP address found, set it to localhost
    if (strIpAddress.isEmpty())
        strIpAddress = QHostAddress(QHostAddress::LocalHost).toString();

    return strIpAddress;

}


void tcp::on_confirm_shareip_clicked() //向用户发送连接请求，注意防火墙
{
    share_ip=ui->share_ip->text();
    socket->connectToHost(share_ip,3005);       //默认传输端口3005
    if(socket->waitForConnected(500))
    {
        connect(socket,&QTcpSocket::disconnected,[=](){
            qDebug()<<"断开连接";
            socket->close();
        });

        QMessageBox::information(this,"tips","连接成功");
        ui->btnDown->setEnabled(true);
        ui->btnFile->setEnabled(true);
        ui->btnSend->setEnabled(true);
        ui->btnLook->setEnabled(true);
    }
    else
    {
        QMessageBox::information(this,"tips","连接失败");
    }
}


void tcp::on_recept_clicked() //开启接收，转换为服务端接收请求
{
    ui->share_ip->setEnabled(false);
    ui->btnDown->setEnabled(false);
    ui->btnFile->setEnabled(false);
    ui->btnSend->setEnabled(false);
    ui->btnLook->setEnabled(false);
    ui->btnC->setEnabled(false);
    server = new QTcpServer(this);
    if(server->listen(QHostAddress::Any,3005)) //默认传输端口3005
    {
        ui->clientFile->append("监听成功");
    }

    connect(server,&QTcpServer::newConnection,[=](){
        socket = server->nextPendingConnection();

    connect(socket,&QTcpSocket::readyRead,this,&tcp::recvData);
    QStringList list = socket->peerAddress().toString().split(":");
    QString ip = list[3];


        ui->clientFile->append(QString("[%1,%2]连接成功").arg(ip).arg(3005));



    });


    connect(myTimer,&QTimer::timeout,[=](){
        myTimer->stop();
        sendData();
    });


}

void tcp::recvData(){
    QByteArray arr = socket->readAll();
    qDebug()<<arr.at(0);
    filePath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);   //默认下载地址为桌面
    if(flag == 1)  //同客户端接收代码
    {
        if(arr.at(0) == '#')
        {

            flag = 2;
            qDebug()<<"--------"<<flag;
            fileName = QString(arr).section("#",1,1);
            fileSize = QString(arr).section("#",2,2).toInt();
            recvSize = 0;
            qDebug()<<"filepath"<<QString("%1/%2").arg(filePath).arg(fileName);
            file.setFileName(QString("%1/%2").arg(filePath).arg(fileName));

            bool isok = file.open(QIODevice::WriteOnly);
            if(isok == false)
            {
                socket->disconnectFromHost();
                socket->close();
            }

            //初始化进度条
            ui->progressBar->setMinimum(0);
            ui->progressBar->setMaximum(fileSize/1024);

        }

    }
    else if(flag == 2)
    {
        //发送过来的是文件
        qint64 len = file.write(arr);
        recvSize +=len;
        ui->progressBar->setValue(recvSize/1024);
        if(recvSize == fileSize)
        {
            ui->clientFile->append("已接受成功");
            file.close();  //关闭文件
            flag = 1;
        }
    }
}


void tcp::on_refresh_clicked() //刷新
{
    tcp *fater = new tcp();
    this->close();
    fater->show();
}

